'use strict';

const Controller = require('egg').Controller;

class MomentController extends Controller {
  // 发布朋友圈
	async create() {
    const { ctx, app } = this;
	  let current_user_id = ctx.authUser.id;
	  // 参数验证
	  ctx.validate({
		 content: {
			 type: 'string',
			 required: false,
			 desc: '内容'
		 },
		 image: {
			 type: 'string',
			 required: false,
			 desc: '图片'
		 },
		 video: {
			 type: 'string',
			 required: false,
			 desc: '视频'
		 },
		 type: {
			 type: 'string',
			 required: true,
			 range: {
				 in: ['content', 'image', 'video']
			 },
			 desc: '朋友圈类型'
		 },
		 location: {
			 type: 'string',
			 required: false,
			 desc: '位置'
		 },
		 remind: {
			 type: 'string',
			 required: false,
			 defValue: "",
			 desc: '提醒谁看'
		 },
		 see: {
			 type: 'string',
			 required: false,
			 defValue: "all",
			 desc: '谁可以看'
		 }
		});
		let { content, image, video, type, location, remind, see } = ctx.request.body;
		// 三个类型都没有
		if (!ctx.request.body[type]) {
			return ctx.apiFail(`${type} 不能为空`);
		}
		let moment = await app.model.Moment.create({
			content, image, video, location, remind, see,
			user_id: current_user_id
		});

		if (!moment) {
			return ctx.apiFail('发布失败');
		}

		// 推送到好友的时间轴
		this.toTimeline(moment);

		ctx.apiSuccess('ok');
  }
	
	// 推送到好友时间轴
	async toTimeline(moment){
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;
		// 获取当前用户所有好友id
		let friends = await app.model.Friend.findAll({
			where: {
				user_id: current_user_id,
				isblack: 0
			},
			attributes: ['friend_id']
		});
		// 谁可以看
		/**
		 * 
		 数据库中的记录  转换成结构化数据
		 all            全部人可看 ['all']
		 only: 1,2,3    指定人可见 ['only','1,2,3']
		 except: 1,2,3  谁不可看 ['except','1,2,3']
		 none            仅自己可见 ['none']
		 */
		let sees = moment.see.split(':')
		let o = {
			only: [],
			except: []
		}
		let oType = sees[0]
		if((sees[0] === 'only' || sees[0]==='except') && sees[1]){
			// 字符串分割成数组再转换成int类型
			o[sees[0]] = (sees[1].split(',')).map(item => parseInt(item))
		}
		// 筛选出需要推送的好友,为none时返回空数组
		let addData = friends.filter(item => {
			return (oType === 'all') 
				|| (oType === 'only' && o.only.includes(item.friend_id))
			  || (oType === 'except' && !o.except.includes(item.friend_id))
		})
		// 好友数据
		addData = addData.map(item => {
			return {
				user_id: item.friend_id,
				moment_id: moment.id,
				own: 0
			}
		});
		// 本人数据
		addData.push({
			user_id: current_user_id,
			moment_id: moment.id,
			own: 1
		});
		// 推送到时间轴当中
		await app.model.MomentTimeline.bulkCreate(addData);

		// 消息推送
		let message = {
			avatar: ctx.authUser.avatar,
			user_id: current_user_id,
			type: "new"
		}

		addData.forEach(item => {
			ctx.sendAndSaveMessage(item.user_id, message, 'moment');
		});

		// 提醒用户
		if (moment.remind) {
			let arr = moment.remind.split(',');
			arr.forEach(user_id => {
				ctx.sendAndSaveMessage(user_id, {
					avatar: ctx.authUser.avatar,
					user_id: current_user_id,
					type: "remind"
				}, 'moment');
			});
		}
		
	}
	
	// 点赞
	async like(){
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;

		ctx.validate({
			id: {
				type: "int",
				required: true,
				desc: "朋友圈id"
			}
		});
		let { id } = ctx.request.body;
		let MomentTimeline = await app.model.MomentTimeline.findOne({
			where: {
				user_id: current_user_id,
				moment_id: id
			},
			include: [{
				model: app.model.Moment,
				attributes: ['user_id'],
				include: [{
					model: app.model.MomentLike,
					attributes: ['user_id'],
				}]
			}]
		});

		if (!MomentTimeline) {
			return ctx.apiFail('朋友圈消息不存在');
		}

		// 是否已点赞过
		let like = await app.model.MomentLike.findOne({
			where: {
				user_id: current_user_id,
				moment_id: id
			}
		});
		
		if (like) {
			await like.destroy();
			return ctx.apiSuccess(MomentTimeline.moment.moment_likes);
		} else {
			await app.model.MomentLike.create({
				user_id: current_user_id,
				moment_id: id
			});
			ctx.apiSuccess(MomentTimeline.moment.moment_likes);
		}
		
		let message = {
			avatar: ctx.authUser.avatar,
			user_id: current_user_id,
			type: "like"
		}

		// 通知作者
		if (MomentTimeline.moment.user_id && MomentTimeline.moment.user_id !== current_user_id) {
			ctx.sendAndSaveMessage(MomentTimeline.moment.user_id, message, 'moment');
		}
		// 通知相关人
		MomentTimeline.moment.moment_likes.forEach(item => {
			if (item.user_id !== current_user_id) {
				ctx.sendAndSaveMessage(item.user_id, message, 'moment');
			}
		});
	}
	
	// 朋友圈评论
	async comment(){
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;

		ctx.validate({
			id: {
				type: "int",
				required: true,
				desc: "朋友圈id"
			},
			content: {
				type: "string",
				required: true,
				desc: "评论内容"
			},
			reply_id: {
				type: "int",
				required: true,
				defValue: 0,
				desc: "回复id"
			}
		});
		let { id, content, reply_id } = ctx.request.body;
		let MomentTimeline = await app.model.MomentTimeline.findOne({
			where: {
				user_id: current_user_id,
				moment_id: id
			},
			include: [{
				model: app.model.Moment,
				attributes: ['user_id'],
				include: [{
					model: app.model.MomentLike,
					attributes: ['user_id']
				}]
			}]
		});

		if (!MomentTimeline) {
			return ctx.apiFail('朋友圈消息不存在');
		}

		let comment = await app.model.MomentComment.create({
			user_id: current_user_id,
			moment_id: id,
			content,
			reply_id
		});

		ctx.apiSuccess(comment);

		let message = {
			avatar: ctx.authUser.avatar,
			user_id: current_user_id,
			type: "comment"
		}
		// 通知作者
		if (MomentTimeline.moment.user_id && MomentTimeline.moment.user_id !== current_user_id) {
			ctx.sendAndSaveMessage(MomentTimeline.moment.user_id, message, 'moment');
		}
		// 通知相关人
		MomentTimeline.moment.moment_likes.forEach(item => {
			if (item.user_id !== current_user_id) {
					ctx.sendAndSaveMessage(item.user_id, message, 'moment');
			}
		});

		// 通知被回复人
		if (reply_id > 0) {
			// 点赞列表包含被回复人,上面已经通知过
			let index = MomentTimeline.moment.moment_likes.findIndex(item => {
				return item.user_id === reply_id
			});

			if (index === -1) {
				ctx.sendAndSaveMessage(reply_id, message, 'moment');
			}
		}
	}

	// 朋友圈列表
	async timeline(){
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;

		let page = ctx.params.page ? parseInt(ctx.params.page) : 1;
		let limit = ctx.query.limit ? parseInt(ctx.query.limit) : 10;
		let offset = (page - 1) * limit;
	
		let rows = await app.model.MomentTimeline.findAll({
			where: {
				user_id: current_user_id
			},
			include:[{
					model: app.model.Moment,
						include: [
						// 发布者信息
						{
							model: app.model.User,
							attributes: ['id','nickname', 'username', 'avatar',]
						},
						// 评论
						{
							model: app.model.MomentComment,
							attributes: {
								exclude: ['created_at', 'updated_at']
							},
							include: [{
								// 评论者
								model: app.model.User,
								as: "momentCommentUser",
								attributes: ['id', 'nickname', 'username']
						  },
							{
								// 回复人
								model: app.model.User,
								as: "momentCommentReply",
								attributes: ['id', 'nickname', 'username']
							}]
						},
						// 点赞
						{
							model: app.model.MomentLike,
							attributes: ['user_id', 'moment_id'],
							include: [{
								model: app.model.User,
								attributes: ['id', 'nickname', 'username']
							}]
						}
					],
				}	
			],
			offset,
			limit,
			order: [
				['id', 'DESC']
			]
		})
		// 当前用户设置看ta的好友id
		let friends = await app.model.Friend.findAll({
			where: {
				user_id: current_user_id,
				// 从自己角度：是否看ta
				lookhim: 1
			},
			attributes: ['friend_id']
		});
		// 好友设置了我可以看ta的好友id
		let bfriends = await app.model.Friend.findAll({
			where: {
				friend_id: current_user_id,
				// 从好友角度：是否允许看我
				lookme: 1
			},
			attributes: ['user_id']
		});
		// 转成id数组
		friends = friends.map(item => item.friend_id);
		bfriends = bfriends.map(item => item.user_id);
		// 权限过滤后的好友
		friends = friends.filter(item => bfriends.includes(item))
		
		let res = [];
		rows.forEach(item => {
			// 发布朋友圈的好友在权限过滤后数组之中，或者是自己发的
			if (friends.includes(item.moment.user_id) || item.moment.user_id === current_user_id) {
				let comments = [];
				item.moment.moment_comments.forEach(v => {
					// 发布评论的好友在权限过滤后数组之中，或者是自己发的
					if (friends.includes(v.momentCommentUser.id) || v.momentCommentUser.id === current_user_id) {
						comments.push({
							content: v.content,
							user: {
								id: v.momentCommentUser.id,
								name: v.momentCommentUser.nickname || v.momentCommentUser.username
							},
							reply: v.momentCommentReply ? {
								id: v.momentCommentReply.id,
								name: v.momentCommentReply.nickname || v.momentCommentReply.username
							} : null
						});
					}
			});

				let likes = [];
				item.moment.moment_likes.forEach(v => {
					// 点赞的好友在权限过滤后数组之中，或者是点的
					if (friends.includes(v.user.id) || v.user.id === current_user_id) {
						likes.push({
							id: v.user.id,
							name: v.user.nickname || v.user.username
						});
					}
				});
		
				res.push({
					// 时间轴id
					id: item.id,
					// 发布者id
					user_id: item.moment.user_id,
					// 发布者昵称
					user_name: item.moment.user.nickname || item.moment.user.username,
					// 发布者头像
					avatar: item.moment.user.avatar,
					// 信息id
					moment_id: item.moment_id,
					// 发布内容
					content: item.moment.content,
					image: item.moment.image ? item.moment.image.split(',') : [],
					video: item.moment.video ? JSON.parse(item.moment.video) : null,
					location: item.moment.location,
					// 是否本人发布
					own: item.own,
					created_at: item.created_at,
					comments,
					likes
				});
			}
		});
		ctx.apiSuccess(res)
		
	}
	
	// 某个用户朋友圈
	async list() {
		const { ctx, app } = this;
		let current_user_id = ctx.authUser.id;

		let page = ctx.params.page ? parseInt(ctx.params.page) : 1;
		let limit = ctx.query.limit ? parseInt(ctx.query.limit) : 10;
		let offset = (page - 1) * limit;
		// 用户id
		let user_id = ctx.query.user_id ? parseInt(ctx.query.user_id) : 0;
		let lookIds = [];
		// 没有传用户id,就查本人朋友圈
		if (user_id == current_user_id || !user_id) {
			// 本人
			user_id = current_user_id;
			lookIds = false;
		} else {
			// 验证我是否具备权限
			let f = await app.model.User.findOne({
				where: {
					id: user_id,
					status: 1
				},
				attributes: ['id', 'nickname', 'username', 'avatar'],
				include: [{
					model: app.model.Friend,
					as: "bfriends",
					where: {
						user_id: current_user_id
					},
					attributes: ['lookhim', 'isblack']
				}, {
					model: app.model.Friend,
					as: "friends",
					where: {
						friend_id: current_user_id
					},
					attributes: ['lookme', 'isblack']
				}]
			});

			// 用户是否存在
			if (!f) {
				return ctx.apiFail('用户不存在或已被禁用');
			}
			// 是否是好友关系
			if (!f.bfriends.length || !f.friends.length) {
				return ctx.apiSuccess([]);
			}
			// 不可见
			if (f.bfriends[0].isblack || f.friends[0].isblack || !f.bfriends[0].lookhim || !f.friends[0].lookme) {
				return ctx.apiSuccess([]);
			}
			// 获取当前用户所有好友（查找共同好友）
			let friends = await app.model.Friend.findAll({
				where: {
					user_id: current_user_id,
					isblack: 0
				},
				attributes: ['friend_id']
			});

			lookIds = friends.map(item => item.friend_id);
	
		}

		let rows = await app.model.Moment.findAll({
			where: {
				user_id
			},
			include: [{
				model: app.model.User,
				attributes: ['id', 'nickname', 'username', 'avatar']
			}, 
			{
				model: app.model.MomentComment,
				attributes: {
					exclude: ['created_at', 'updated_at']
				},
				include: [{
					model: app.model.User,
					as: "momentCommentUser",
					attributes: ['id', 'nickname', 'username']
				}, {
					model: app.model.User,
					as: "momentCommentReply",
					attributes: ['id', 'nickname', 'username']
				}]
			}, 
			{
				model: app.model.MomentLike,
				attributes: ['user_id', 'moment_id'],
				include: [{
					model: app.model.User,
					attributes: ['id', 'nickname', 'username']
				}]
			}],
			offset,
			limit,
			order: [
				['id', 'DESC']
			]
		});

		let res = [];
		rows.forEach(item => {
			let comments = [];
			item.moment_comments.forEach(v => {
				if (!lookIds || lookIds.includes(v.momentCommentUser.id) || v.momentCommentUser.id === current_user_id) {
						comments.push({
							content: v.content,
							user: {
								id: v.momentCommentUser.id,
								name: v.momentCommentUser.nickname || v.momentCommentUser.username
							},
							reply: v.momentCommentReply ? {
								id: v.momentCommentReply.id,
								name: v.momentCommentReply.nickname || v.momentCommentReply.username
							} : null
						})
					}
				});

				let likes = [];
				item.moment_likes.forEach(v => {
					if (!lookIds || lookIds.includes(v.user.id) || v.user.id === current_user_id) {
						likes.push({
							id: v.user.id,
							name: v.user.nickname || v.user.username
						});
					}
				});

				res.push({
					user_id: item.user_id,
					user_name: item.user.nickname || item.user.username,
					avatar: item.user.avatar,
					moment_id: item.id,
					content: item.content,
					image: item.image ? item.image.split(',') : [],
					video: item.video ? JSON.parse(item.video) : null,
					location: item.location,
					own: 1,
					created_at: item.created_at,
					comments,
					likes
				});
		});
		ctx.apiSuccess(res);
	}
	
}

module.exports = MomentController;
